/**
 * JWT工具类
 */
export class JWTUtils {
    /**
     * 解析JWT Token
     * @param {string} token - JWT token
     * @returns {Object|null} 解析后的payload或null
     */
    static parseJWT(token) {
        if (!token || typeof token !== 'string') {
            return null;
        }

        try {
            // 分割JWT字符串
            const parts = token.split('.');
            if (parts.length !== 3) {
                throw new Error('Invalid JWT format');
            }

            // Base64 URL解码函数
            const base64UrlDecode = (str) => {
                // 替换URL安全字符
                str = str.replace(/-/g, '+').replace(/_/g, '/');

                // 补齐padding
                while (str.length % 4) {
                    str += '=';
                }

                try {
                    return atob(str);
                } catch (e) {
                    throw new Error('Invalid base64 encoding');
                }
            };

            // 解码header和payload
            const header = JSON.parse(base64UrlDecode(parts[0]));
            const payload = JSON.parse(base64UrlDecode(parts[1]));

            return {
                header,
                payload,
                signature: parts[2]
            };
        } catch (error) {
            console.error('JWT parsing error:', error);
            return null;
        }
    }

    /**
     * 检查JWT是否过期
     * @param {string} token - JWT token
     * @returns {boolean} true表示已过期
     */
    static isExpired(token) {
        const decoded = this.parseJWT(token);

        if (!decoded || !decoded.payload.exp) {
            // 如果没有过期时间，认为永不过期
            return false;
        }

        const currentTime = Math.floor(Date.now() / 1000);
        return decoded.payload.exp < currentTime;
    }

    /**
     * 检查JWT是否即将过期（默认5分钟内）
     * @param {string} token - JWT token
     * @param {number} bufferTime - 缓冲时间（秒），默认300秒（5分钟）
     * @returns {boolean} true表示即将过期
     */
    static isExpiringSoon(token, bufferTime = 300) {
        const decoded = this.parseJWT(token);

        if (!decoded || !decoded.payload.exp) {
            return false;
        }

        const currentTime = Math.floor(Date.now() / 1000);
        return decoded.payload.exp < (currentTime + bufferTime);
    }

    /**
     * 获取JWT的剩余有效时间（秒）
     * @param {string} token - JWT token
     * @returns {number} 剩余秒数，-1表示已过期或无效
     */
    static getRemainingTime(token) {
        const decoded = this.parseJWT(token);

        if (!decoded || !decoded.payload.exp) {
            return -1;
        }

        const currentTime = Math.floor(Date.now() / 1000);
        const remainingTime = decoded.payload.exp - currentTime;

        return remainingTime > 0 ? remainingTime : -1;
    }

    /**
     * 验证JWT的基本格式
     * @param {string} token - JWT token
     * @returns {boolean} true表示格式有效
     */
    static isValidFormat(token) {
        return this.parseJWT(token) !== null;
    }

    /**
     * 从token中提取用户信息
     * @param {string} token - JWT token
     * @returns {Object|null} 用户信息或null
     */
    static getUserInfo(token) {
        const decoded = this.parseJWT(token);
        return decoded ? decoded.payload : null;
    }

    /**
     * 安全地存储JWT
     * @param {string} token - JWT token
     */
    static storeToken(token) {
        if (!token) {
            return;
        }

        try {
            localStorage.setItem('Authorization', token);
        } catch (error) {
            console.error('Failed to store token:', error);
        }
    }

    /**
     * 安全地获取JWT
     * @returns {string|null} JWT token或null
     */
    static getToken() {
        try {
            return localStorage.getItem('Authorization');
        } catch (error) {
            console.error('Failed to get token:', error);
            return null;
        }
    }

    /**
     * 清除存储的JWT
     */
    static removeToken() {
        try {
            localStorage.removeItem('Authorization');
        } catch (error) {
            console.error('Failed to remove token:', error);
        }
    }

    /**
     * 检查当前用户是否已认证
     * @returns {boolean} true表示已认证且token有效
     */
    static isAuthenticated() {
        const token = this.getToken();
        return token && this.isValidFormat(token) && !this.isExpired(token);
    }
}

/**
 * 认证守卫 - 用于路由保护
 */
export class AuthGuard {
    /**
     * 检查路由访问权限
     * @param {Object} to - 目标路由
     * @param {Object} from - 来源路由
     * @param {Function} next - 导航函数
     */
    static checkAuth(to, from, next) {
        const requiresAuth = to.meta.requiresAuth;

        if (requiresAuth === false) {
            // 明确标记不需要认证
            next();
            return;
        }

        if (requiresAuth === true || requiresAuth === undefined) {
            // 需要认证或未明确标记
            if (JWTUtils.isAuthenticated()) {
                next();
            } else {
                // 清理过期token
                JWTUtils.removeToken();
                next({ name: 'login', query: { redirect: to.fullPath } });
            }
        } else {
            next();
        }
    }

    /**
     * 自动刷新token的守卫
     * @param {Function} refreshTokenFn - 刷新token的函数
     */
    static autoRefreshGuard(refreshTokenFn) {
        return (to, from, next) => {
            const token = JWTUtils.getToken();

            if (token && JWTUtils.isExpiringSoon(token)) {
                // Token即将过期，尝试刷新
                refreshTokenFn()
                    .then(() => next())
                    .catch(() => {
                        JWTUtils.removeToken();
                        next({ name: 'login', query: { redirect: to.fullPath } });
                    });
            } else {
                next();
            }
        };
    }
}
